package zdream.pmfield.test.stage.battle;

import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.atomic.AtomicBoolean;

import zdream.pmfield.core.Result;
import zdream.pmfield.data.foe.Foe;
import zdream.pmfield.data.foe.MoveTemplate;
import zdream.pmfield.stage.StageBuilderForTest;
import zdream.pmfield.stage.StageWrapper;
import zdream.pmfield.stage.action.DazeAction;
import zdream.pmfield.stage.message.ActionRequestMessage;
import zdream.pmfield.stage.message.ActionRequestReply;
import zdream.pmfield.stage.message.ActionStartMessage;
import zdream.pmfield.stage.message.TurnFinishedMessage;
import zdream.pmfield.storage.FoeTemplateStorage;
import zdream.pmfield.test.utils.ResourceConstant;

import static org.junit.Assert.*;

/**
 * @author Zdream
 * @date 2023-12-03
 * @since 0.0.1
 */
public class SkipTurnCase {
	FoeTemplateStorage storage;

	@Before
	public void before() {
		storage = new FoeTemplateStorage();
		storage.load();
		storage.loadMovesInResource(ResourceConstant.RES_PATH_TEST_MOVES_JSON);
	}

	@Test
	public void testUseSkipTurnMove() {
		MoveTemplate skippedMove = storage.findMoveById(10001, 1);
		assertEquals(skippedMove.name, "跳过回合");

		Foe foe1 = Foe.builder(storage.findFoeById(4))
				.withLevel(20)
				.withMove(skippedMove)
				.build();
		Foe foe2 = Foe.builder(storage.findFoeById(1))
				.withLevel(20)
				.withMove(skippedMove)
				.build();
		final StageWrapper wrapper = StageBuilderForTest.builder()
				.withStorage(storage)
				.putFoeToOneSide(foe1)
				.putFoeToAnotherSide(foe2)
				.buildWrapper();

		System.out.println("测试: 跳过回合后下一轮是另一个 turn");
		AtomicBoolean actionRequested = new AtomicBoolean(false);
		AtomicBoolean actionStarted = new AtomicBoolean(false);
		AtomicBoolean turnFinished = new AtomicBoolean(false);
		AtomicBoolean checked = new AtomicBoolean(false);

		wrapper.printBeforeHandleMessage();
		wrapper.onDefaultActionRequest();
		wrapper.onMessage(ActionRequestMessage.class, message -> {
			if (actionRequested.get()) {
				assertTrue(turnFinished.get());
				assertTrue(actionStarted.get());
				checked.set(true);
			}
			actionRequested.set(true);
		});
		wrapper.onMessage(ActionStartMessage.class, message -> {
			assertTrue(actionRequested.get());
			assertTrue(message.action.isForDaze());
			actionStarted.set(true);
		});
		wrapper.onMessage(TurnFinishedMessage.class, message -> turnFinished.set(true));

		wrapper.runUntil(stage -> checked.get());
	}

	@Test
	public void testSkipTurnByDazeAction() {
		MoveTemplate normalMove = storage.findMoveById(1, 1);

		Foe foe1 = Foe.builder(storage.findFoeById(4))
				.withLevel(20)
				.withMove(normalMove)
				.build();
		Foe foe2 = Foe.builder(storage.findFoeById(1))
				.withLevel(20)
				.withMove(normalMove)
				.build();
		final StageWrapper wrapper = StageBuilderForTest.builder()
				.putFoeToOneSide(foe1)
				.putFoeToAnotherSide(foe2)
				.withStorage(storage)
				.buildWrapper();

		System.out.println("测试: 跳过回合后下一轮是另一个 turn");
		AtomicBoolean actionRequested = new AtomicBoolean(false);
		AtomicBoolean actionStarted = new AtomicBoolean(false);
		AtomicBoolean turnFinished = new AtomicBoolean(false);
		AtomicBoolean checked = new AtomicBoolean(false);

		wrapper.printBeforeHandleMessage();
		wrapper.onMessage(ActionRequestMessage.class, message -> {
			final ActionRequestReply reply = message.createReplyTemplate();
			reply.action = new DazeAction(message.foe);
			final Result result = message.commit(reply);
			assertTrue(result.errorMessage, result.success);
		});
		wrapper.onMessage(ActionRequestMessage.class, message -> {
			if (actionRequested.get()) {
				assertTrue(turnFinished.get());
				assertTrue(actionStarted.get());
				checked.set(true);
			}
			actionRequested.set(true);
		});
		wrapper.onMessage(ActionStartMessage.class, message -> {
			assertTrue(actionRequested.get());
			assertTrue(message.action.isForDaze());
			actionStarted.set(true);
		});
		wrapper.onMessage(TurnFinishedMessage.class, message -> turnFinished.set(true));

		wrapper.runUntil(stage -> checked.get());

	}
}
